<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>生成器</title>
	<!--<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>-->
</head>
<body>
<script>
	//ES6引入的新的数据类型，一个生成器就像一个函数，但可以多次返回
	function foo(x) {
		return x + x;
	}
	console.log("foo():" +foo(1));

	//generator
	function* fooGen() {
		yield x + 1;
		yield x + 2;
		return x + 3;
	}

	//斐波那契数列
	function fib(max) {
		var
			t,
			a = 0,
			b = 1,
			arr = [0,1];
		while (arr.length < max) {
			[a,b] = [b,a + b];
			arr.push(b);
		}
		return arr;
	}
	//测试斐波那契数列
	console.log("fib(4):" + fib(4));

	function* fibGen(max) {
		let
			a = 0,
		  b = 1,
			n = 0;
		while (max > n) {
			yield a;
			[a,b] = [b,a + b];
			n++;
		}
		return;
	}
	//直接调用生成器回返回一个生成器对象，还没去执行
	//console.log("fibGen(4):" + fibGen(4));
	var f = fibGen(4);
	// console.log("f.next():" + f.next());
	// console.log("f.next():" + f.next());
	// console.log("f.next():" + f.next());
	// console.log("f.next():" + f.next());
	// console.log("f.next():" + f.next());

	for (let val of fibGen(5)) {
		console.log("val:" + val);
	}

	//generator可以在执行的过程中多次返回，所以看上去就像可以记住状态的函数
	//利用这一点，写一个generator就可以实现需要使用面向对象才能实现的功能;

	let fibObj = {
		a:0,
		b:1,
		i:0,
		max:5,
		next:function () {
			let
				r = this.a,
				t = this.a + this.b;
			this.a = this.b;
			this.b = t;
			if (this.i < this.max) {
				this.i++;
				return r;
			} else {
				return undefined;
			}
		}
	};
	//调用fibObj.next();
	console.log("fibObj.next():" + fibObj.next());
	console.log("fibObj.next():" + fibObj.next());
	console.log("fibObj.next():" + fibObj.next());
	console.log("fibObj.next():" + fibObj.next());
	console.log("fibObj.next():" + fibObj.next());
	console.log("fibObj.next():" + fibObj.next());
	console.log("fibObj.next():" + fibObj.next());

	//利用生成器来实现一个计数器
	// function* next_id() {
	// 	for (let i=1; i<100; i++) {
	// 		yield i;
	// 	}
	// }

	function* next_id() {
		for (let i=1; i<100; i++) {
			yield i;
		}
	}
	for (let val of next_id()) {
		console.log("next_id:" + val);
	}
</script>
</body>
</html>